# -*- coding: utf-8 -*-
# 如果你的程序（包括注释）中包含中文，请加上上面这一行，用于指明编码（utf-8）。
# #号开头的行都是注释。

# 如何编辑本程序：
#     用任何文本编辑器均可编辑。

# 如何运行本程序：
#     在终端中，运行：python pA02_example.py
#
# 依赖模块：
#     pandas       (pip install pandas)
#     scikit-learn (pip install scikit-learn)
#     matplotlib   (pip install matplotlib)
#
# 依赖数据集：
#     USDA Food dataset:   https://gitee.com/hobbiton/pydata-book/raw/2nd-edition/datasets/usda_food/database.json

import json
import pandas as pd
import scipy.cluster.hierarchy as hclust
import matplotlib.pyplot as plt

# 读取json数据：
with open('datasets/usda_food/database.json') as f:
	db = json.load(f)

# 查看db内容：
# type(db)
# len(db)
# type(db[0])
    
# 将每种食品的基本信息装入DataFrame：
info = pd.DataFrame(db, columns=['id', 'description', 'group'])
info = info.rename(columns={'description':'food', 'group':'fgroup'}, copy=False)

# 选取其中的一类食品：
#fast_foods_info = info[info['fgroup']=='Fast Foods'].set_index(['id'])
fast_foods_info = info[info['fgroup']=='Restaurant Foods'].set_index(['id'])

# 将每种食品的营养成分装入DataFrame：
pieces = []
for food in db:
	food_nutrients = pd.DataFrame(food['nutrients'])
	food_nutrients['id'] = food['id']
	pieces.append(food_nutrients)

nutrients = pd.concat(pieces, ignore_index = True)
nutrients = nutrients.drop_duplicates()
nutrients = nutrients.rename(columns={'description':'nutrient', 'group':'ngroup'}, copy=False)

# 这是所有营养成分的名单（94种）：
nutrients_names = nutrients['nutrient'].unique() # a list of all nutrients' names.

# 将营养成分按食品id和营养成分分组：
# Actually there is only one value for each combination of 'id' and 'nutrient',
# but we have to use an aggregate function such as mean() anyway.
nutrients_by_food = nutrients[['id', 'nutrient', 'value']].groupby(['id','nutrient']).mean()

# 变成每行一种食品、每列一种营养成分的形式（矩阵形式）：
nutrients_mat = nutrients_by_food.unstack()
nutrients_mat.fillna(0, inplace=True)

# 计算每种营养成分（每列）的均值和标准差：
nutrients_mean = nutrients_mat.mean() # mean for each nutrient
nutrients_std = nutrients_mat.std() # stdev for each nutrient

# 对每一列营养成分数据进行z-分数规范化：
(rows, cols) = nutrients_mat.shape
for col_id in range(cols):
    nutrients_mat.iloc[:, col_id] = nutrients_mat.iloc[:, col_id].map(lambda x: (x-nutrients_mean[col_id])/nutrients_std[col_id])
# Now nutrients_mat is normalized.

# 选取某一类食品：
# Nutrients of all fast foods (365 rows, 94 columns):
fast_foods_nutrients = nutrients_mat.loc[fast_foods_info.index]

# 根据食品的营养成分相似度，用层次聚类方法进行聚类分析，并画树状图：
dend = hclust.dendrogram(hclust.linkage(fast_foods_nutrients, method='ward'), labels=fast_foods_nutrients.index)

# 显示树状图：
plt.show()


    




	
	